// Copyright Epic Games, Inc. All Rights Reserved.

#include "TDM_PlayerSpawningManagmentComponent.h" // 引入对应的头文件

#include "Engine/World.h" // 引入世界类
#include "GameFramework/PlayerState.h" // 引入玩家状态类
#include "GameModes/LyraGameState.h" // 引入Lyra游戏状态类
#include "Player/LyraPlayerStart.h" // 引入Lyra玩家出生点类
#include "Teams/LyraTeamSubsystem.h" // 引入Lyra团队子系统

#include UE_INLINE_GENERATED_CPP_BY_NAME(TDM_PlayerSpawningManagmentComponent) // 引入UE生成的代码

class AActor; // 前向声明AActor类

UTDM_PlayerSpawningManagmentComponent::UTDM_PlayerSpawningManagmentComponent(const FObjectInitializer& ObjectInitializer) // 构造函数定义
	: Super(ObjectInitializer) // 调用父类构造函数
{
	// 构造函数体为空
}

AActor* UTDM_PlayerSpawningManagmentComponent::OnChoosePlayerStart(AController* Player, TArray<ALyraPlayerStart*>& PlayerStarts) // 选择玩家出生点函数实现
{
	ULyraTeamSubsystem* TeamSubsystem = GetWorld()->GetSubsystem<ULyraTeamSubsystem>(); // 获取团队子系统
	if (!ensure(TeamSubsystem)) // 确保团队子系统存在
	{
		return nullptr; // 返回空指针
	}

	const int32 PlayerTeamId = TeamSubsystem->FindTeamFromObject(Player); // 查找玩家所属团队ID

	// 此时应该已经有团队ID了，但是登录后的早期处理可能会尝试做一些事情，忽略它。
	if (!ensure(PlayerTeamId != INDEX_NONE)) // 确保玩家团队ID有效
	{
		return nullptr; // 返回空指针
	}

	ALyraGameState* GameState = GetGameStateChecked<ALyraGameState>(); // 获取游戏状态

	ALyraPlayerStart* BestPlayerStart = nullptr; // 最佳出生点
	double MaxDistance = 0; // 最大距离
	ALyraPlayerStart* FallbackPlayerStart = nullptr; // 备用出生点
	double FallbackMaxDistance = 0; // 备用最大距离

	for (APlayerState* PS : GameState->PlayerArray) // 遍历游戏状态中的玩家数组
	{
		const int32 TeamId = TeamSubsystem->FindTeamFromObject(PS); // 查找当前遍历玩家的团队ID
		
		// 此时应该已经有团队ID了...
		if (PS->IsOnlyASpectator() || !ensure(TeamId != INDEX_NONE)) // 如果是旁观者或团队ID无效
		{
			continue; // 跳过此玩家
		}

		// 如果其他玩家不在同一团队，让我们找到离他们最远的出生点。
		if (TeamId != PlayerTeamId) // 如果团队ID不等于当前玩家团队ID
		{
			for (ALyraPlayerStart* PlayerStart : PlayerStarts) // 遍历所有玩家出生点
			{
				if (APawn* Pawn = PS->GetPawn()) // 获取当前遍历玩家的Pawn
				{
					const double Distance = PlayerStart->GetDistanceTo(Pawn); // 计算出生点到该Pawn的距离

					if (PlayerStart->IsClaimed()) // 如果出生点已被占用
					{
						if (FallbackPlayerStart == nullptr || Distance > FallbackMaxDistance) // 如果备用出生点为空或距离大于备用最大距离
						{
							FallbackPlayerStart = PlayerStart; // 更新备用出生点
							FallbackMaxDistance = Distance; // 更新备用最大距离
						}
					}
					else if (PlayerStart->GetLocationOccupancy(Player) < ELyraPlayerStartLocationOccupancy::Full) // 如果出生点未被占用且位置占用情况未满
					{
						if (BestPlayerStart == nullptr || Distance > MaxDistance) // 如果最佳出生点为空或距离大于最大距离
						{
							BestPlayerStart = PlayerStart; // 更新最佳出生点
							MaxDistance = Distance; // 更新最大距离
						}
					}
				}
			}
		}
	}

	if (BestPlayerStart) // 如果存在最佳出生点
	{
		return BestPlayerStart; // 返回最佳出生点
	}

	return FallbackPlayerStart; // 返回备用出生点
}

void UTDM_PlayerSpawningManagmentComponent::OnFinishRestartPlayer(AController* Player, const FRotator& StartRotation) // 完成重启玩家函数实现
{
	// 函数体为空
}